import { LazyList, LazyNumber } from "./types"
import { map, repeat, take, zip } from "./common"
import { multiply, power, range } from "./number"
import { printLazyPairList, printList } from "./types"

///////////////////////// range /////////////////////////

const nat = range(() => 0)

nat()
// printList(nat)

///////////////////////// map /////////////////////////

const l2 = map
    ((x: LazyNumber) => () => (x() * x()))
    (range(() => 10))

l2()
// printList(l2)

///////////////////////// zip /////////////////////////

const lps = zip<number, number>
    (
        range(() => 10)
    )(
        range(() => 3)
    )

lps()
printLazyPairList(lps)

///////////////////////// repeat /////////////////////////

// [y^x, y^x^x, y^x^x^x, ...]
const powInf =
    (base: LazyNumber) =>
        (times: LazyNumber)
            : LazyList<number> =>
            repeat
                (multiply(times))
                (base)


const allow1bit = powInf
    (() => 1)
    (() => 2)

allow1bit()
// printList(take(() => 11, allow1bit))